package cn.com.algery.temp.service.serviceImpl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Service;

import cn.com.algery.temp.dao.ActivitiMapper;
import cn.com.algery.temp.domain.Page;
import cn.com.algery.temp.domain.Server;
import cn.com.algery.temp.domain.ServerBytes;
import cn.com.algery.temp.service.ServerService;
import cn.com.algery.temp.util.Util;
import cn.com.algery.temp.util.activitiUtil;
import net.sf.json.JSONObject;

@Service
public class ServerServiceImpl implements ServerService {
	@Resource
	private ActivitiMapper	activitiMapper;

	public static String path = "C:\\data";

	public List<Server> getAllFile(String path, String serverName) {

		List<Server> servers = new ArrayList<Server>();
		File directory = new File(path);
		File[] files = directory.listFiles();
		for (File file : files) {
			if (!file.isDirectory()) {
				// System.out.println("server:"+serverName+"/t file:"+file.getName());
				if (serverName == null || file.getName().toUpperCase().contains(serverName.toUpperCase())) {
					// System.out.println(file.getName());
					try {
						String jsonContext = new Util().ReadSelectFile(file);
						JSONObject jsonObject = JSONObject.fromObject(jsonContext);
						Server server = (Server) JSONObject.toBean(jsonObject, Server.class);
						servers.add(server);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
		return servers;
	}

	@Override
	public boolean addServer(Server server,String user_account) throws IOException {
		System.out.println("server_name:" + server.getServer_name());
		File file = new File(path + "\\" + server.getServer_name() + ".json");
		JSONObject jsonObject = JSONObject.fromObject(server);
		System.out.println("json:" + jsonObject.toString());
		try {
			if (!file.exists()) {
				file.createNewFile();
				FileWriter fw = new FileWriter(file, true);
				fw.write(jsonObject.toString());
				fw.close();
				// Initiating process
				IdentityService identityService = activitiUtil.getIdentityService();
				identityService.setAuthenticatedUserId(user_account);
				Map<String,Object> variables = new HashMap<>();
				
				// Call the external interface to find out who the employee's approver is.
				variables.put("user_account", "john");
				variables.put("server", server);
				variables.put("server_name", server.getServer_name());
				activitiUtil.startProcess("mainProcess", server.getServer_name(), variables);
				return true;
			} else {
				return false;// File already exists
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	@Override
	public boolean isUnExistsedServer(String server_name) {
		System.out.println("server_name:" + server_name);
		File file = new File(path + "\\" + server_name + ".json");
		if (file.exists()) {
			return false; // File already exists
		} else {
			return true;// File do not exists
		}	
	}

	@Override
	public boolean updateServer(Server server) {
		File file = new File(path + "\\" + server.getServer_name() + ".json");
		JSONObject jsonObject = JSONObject.fromObject(server);
		System.out.println("json:" + jsonObject.toString());
		try {
			file.delete();
			file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		try {
			FileWriter fw = new FileWriter(file, true);
			fw.write(jsonObject.toString());
			fw.close();
			return true;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public boolean deleteServerByName(String serverName) {
		if(serverName == null ||"".equals(serverName)) {
			serverName = "null";
		}
		System.out.println(path + "\\" + serverName + ".json");
		File file = new File(path + "\\" + serverName + ".json");
		if (file.exists()) {
			System.out.println("file exists");
		}
		if (file.exists() && file.isFile()) {
			file.delete();
			return true;
		}
		return false;
	}

	@Override
	public List<Server> queryServerByName(String serverName) {
		List<Server> servers = new ArrayList<Server>();
		servers = this.getAllFile(path, serverName);

		return servers;
	}

	@Override
	public Map<String, Object> queryServerInList(Page page) {
		List<Server> servers = new ArrayList<Server>();
		servers = this.getAllFile(path, page.getFilterItem());
		if (page.getPage() == null){
	        page.setPage(1);
	    }
		//page.setPageSize(10);
		Integer start = ((page.getPage() - 1) * page.getLimit());
		Integer end = servers.size();
		Map<String, Object> map = new HashMap<>();
		map.put("total", servers.size());
		if(servers.size()-start<page.getLimit()) {//Is it the last page
			end = servers.size();
		} else {
			end = page.getPage() * page.getLimit();
		}
		List<Server> dataList = servers.subList(start,end);
		map.put("dataList", dataList);
		return map;
	}

	@Override
	public List<Server> findAll() {
		List<Server> servers = new ArrayList<Server>();
		servers = this.getAllFile(path, null);
		return servers;
	}

	@Override
	public Server findServerByName(String serverName) {
		File file = new File(path + "\\" + serverName + ".json");
		if (!file.exists()) {
			return new Server();
		}
		String jsonContext = new Util().ReadSelectFile(file);
		JSONObject jsonObject = JSONObject.fromObject(jsonContext);
		Server server = (Server) JSONObject.toBean(jsonObject, Server.class);
		return server;
	}

	@Override
	public Map<String, Object> queryMyTodoList(String user_account,Page page) {
		 TaskService taskService = activitiUtil.getTaskService();
		 Integer limit = page.getLimit();
		 Integer startNum = ( page.getPage() - 1 ) * limit;
		 List<Task> taskList = activitiUtil.findTask(user_account,"mainProcess",startNum,limit,page.getFilterItem());
		 Map<String, Object> map = new HashMap<>();
		 List<Object> servers = new ArrayList<>();
		 for(Task task: taskList) {
			 Map<String, Object> tempServerMap = new HashMap<>();
			 Server tempServer = (Server)taskService.getVariable(task.getId(), "server");
			 if(tempServer != null && !"".equals(tempServer.getServer_name())) {
				 tempServerMap.put("taskId", task.getId());
				 tempServerMap.put("server", tempServer);
				 servers.add(tempServerMap);
			 }
		 }
		 Integer total = activitiUtil.getTasksCount(user_account,"mainProcess",page.getFilterItem());
		 map.put("dataList", servers);
		 map.put("total", total);
		return map;
	}

	@Override
	public Map<String, Object> queryMyApplication(String user_account,Page page) {
		 Map<String, Object> map = new HashMap<>();
		 List<Server> servers = new ArrayList<Server>();
		 Integer limit = page.getLimit();
		 Integer startNum = ( page.getPage() - 1 ) * limit;
		 List<ServerBytes> serverStrs = activitiMapper.getMyApplication(user_account,"server","mainProcess",startNum,limit);
		 for(ServerBytes serverBytes : serverStrs) {
			 Server tempServer = (Server)byteArrayToObject(serverBytes.getBytes());
			 servers.add(tempServer);
		 }
		 Integer total = activitiMapper.getmyApplicationCount(user_account,"server","mainProcess");
		 map.put("dataList", servers);
		 map.put("total", total);
		return map;
	}
	
	/**
     * Object to Byte array
     * @param obj
     * @return
     */
    public static byte[] objectToByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(obj);
            objectOutputStream.flush();
            bytes = byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
		    e.printStackTrace();
        }
        return bytes;
    }

    /**
     * Byte array to object
     * @param bytes
     * @return
     */
    public static Object byteArrayToObject(byte[] bytes) {
        Object obj = null;
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;
        try {
            byteArrayInputStream = new ByteArrayInputStream(bytes);
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            obj = objectInputStream.readObject();
        } catch (Exception e) {
		    e.printStackTrace();
        }
        return obj;
    }

	@Override
	public boolean approve(String taskId, String isApproval,Map<String, Object> variables) {
		if("Y".equals(isApproval)) {
			TaskService taskService = activitiUtil.getTaskService();
			taskService.complete(taskId, variables);
			return true;
		}
		return false;
	}

}
